package com.qingcheng.service.impl;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.qingcheng.pojo.goods.Category;
import com.qingcheng.pojo.goods.Sku;
import com.qingcheng.pojo.order.OrderItem;
import com.qingcheng.service.goods.CategoryService;
import com.qingcheng.service.goods.SkuService;
import com.qingcheng.service.order.CartService;
import com.qingcheng.service.order.PreferentialService;
import com.qingcheng.util.IdWorker;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Title: CartServiceImpl
 * @Description:
 * @Auther:
 * @Version: 1.0
 * @create 2021/10/12 9:29
 */
@Service
public class CartServiceImpl implements CartService {

    @Autowired
    private RedisTemplate redisTemplate;//操作redis

    @Reference
    private SkuService skuService;

    @Reference
    private CategoryService categoryService;

    @Autowired
    private IdWorker idWorker;

    @Autowired
    private PreferentialService preferentialService;
    @Override
    public List<Map<String, Object>> findCart(String name) {
        List<Map<String, Object>> cart_list = (List<Map<String, Object>>) redisTemplate.boundHashOps("CART_LIST").get(name);
        if(cart_list == null){
            cart_list = new ArrayList<>();
        }
        return cart_list;
    }

    /**
     * 加入购物车xxx
     * @param name  登录人
     * @param skuId  skuID
     * @param num     修改的数量   正数：加 负数：减
     */
    @Override
    public void addCartItem(String name, String skuId, Integer num) {
        //1. 获取已有的购物车，判断有没有
        List<Map<String, Object>> cartList = (List<Map<String, Object>>) redisTemplate.boundHashOps("CART_LIST").get(name);
        if(cartList==null){//空购物车，第一次使用这个购物车
            cartList=new ArrayList<Map<String,Object>>();
            if(num<=0){
                return;
            }
            Map newCartItem = createNewCartItem(skuId, num);
            cartList.add(newCartItem);
        }else{//不是第一次
            // 新增商品是否已经在购物车里面
            boolean flag = false;
            for (Map cartItemMap : cartList){
                 OrderItem orderItem = (OrderItem) cartItemMap.get("item");
                 if(orderItem.getSkuId().equals(skuId)){//购物车里面存在
                     //修改购物车的数量
                     int weight1 = orderItem.getWeight() / orderItem.getNum();//单价的重量
                     orderItem.setNum(orderItem.getNum()+num);
                     //数量的改变也会触发，重量的改变，总价的改变
                     orderItem.setWeight(weight1*orderItem.getNum());
                     orderItem.setMoney(orderItem.getPrice()*orderItem.getNum());
                     //如果数量改变之后变成0，就代表需要移除该 购物车项
                     if(orderItem.getNum()<=0){
                         cartList.remove(cartItemMap);
                     }
                     flag = true;
                     break;
                 }
            }
            if(!flag){//不存在
                if(num<=0){
                    return;
                }
                //新增一个购物车项
                Map newCartItem = createNewCartItem(skuId, num);
                cartList.add(newCartItem);
              }
        }
        //2.  循环判断是否已经购买过
        // 如果购买过，就直接修改数量

        //如果没有购买过，创建一个Map：购物车项
       redisTemplate.boundHashOps("CART_LIST").put(name,cartList);

    }

    @Override
    public void updateCartItemChecked(String name, String skuId, Boolean checked) {
        //1. 从redis中获取购物车
        List<Map<String, Object>> cart = findCart(name);
        //2. 遍历购物车项找到对应的商品
        for (Map cartItem : cart){
            OrderItem item = (OrderItem) cartItem.get("item");
            if (item.getSkuId().equals(skuId)){//找到修改状态的购物车项
                cartItem.put("checked",checked); //3. 改状态
                redisTemplate.boundHashOps("CART_LIST").put(name,cart); //4.同步redis的数据
                break;
            }
        }
    }

    @Override
    public void deleteCheckedCartItems(String name) {
        //1. 获取购物车数据
        //1. 从redis中获取购物车
        List<Map<String, Object>> cart = findCart(name);
        //2. 遍历购物项，找到checked 为true 购物车项一处
        //3.同步缓存数据
        Iterator<Map<String, Object>> iterator = cart.iterator();
        while(iterator.hasNext()){
            Map<String, Object> cartItemMap = iterator.next();
            if ((boolean)cartItemMap.get("checked")) {//找到修改状态的购物车项
                iterator.remove();
            }
        }
        redisTemplate.boundHashOps("CART_LIST").put(name,cart); //4.同步redis的数据
    }

    @Override
    public Integer getPreferentialMoney(String name) {
        /**
         *  服装类：  1
         *  生活类： 2
         *  学习用品： 3
         *
         *    1     1000    200    2021/10/14 2021/10/15   1
         *    2     100     10      2021/10/14 2021/10/15   1
         *    1     500     50    2021/10/14 2021/10/15   1
         *
         *
         *
         *    生活品  1     200   10
         *
         *    上衣   1     200
         *    裤子   1     100
         *    鞋子   1     900
         *  1  服装类       1200   ---200
         *      查询优惠表中 优惠的金额
         *      select pre_money from tb_prexxx where category_id = ? and buy_money <= xxxx and state = '1' and create_date <= now() and end_time >=now()
         *
         *
         *
         *
         *   200+10 = 210
         */
        //1. 从redis 获取准备购买了哪些商品
        List<Map<String, Object>> cart = findCart(name);
        List<OrderItem> checekdCartItems = cart.stream().filter(e -> (boolean) e.get("checked") == true).map(e -> (OrderItem) e.get("item")).collect(Collectors.toList());

        //2. 讲商品进行分组 --- 计算每个品类一共花了xxx钱
        // select sum(xxx) from xx group by xxx
        // key: 分类ID   value:总的钱
        //1      10000
        //2      20000
        Map<Integer, IntSummaryStatistics> collect = checekdCartItems.stream().collect(Collectors.groupingBy(OrderItem::getCategoryId3, Collectors.summarizingInt(OrderItem::getMoney)));

        //3. 遍历每个品类，分别计算对应的优惠价格
        int totalPreMoney =0 ;
        Set<Integer> categoryIds = collect.keySet();
        for (Integer categoryId : categoryIds){
            long sum = collect.get(categoryId).getSum();
            // categoryId   sum
            //select pre_money from tb_prexxx where category_id = ? and buy_money <= xxxx and state = '1' and create_date <= now() and end_time >=now()
            int preMoney = preferentialService.coutPreMoney(categoryId, sum);
            totalPreMoney+= preMoney;

        }


        //4. 讲所有的优惠价格进行累加




        return totalPreMoney;
    }

    @Override
    public List<OrderItem> getBuyOrderItems(String name) {
        //1. 获取这个人的所有的购物车信息
        List<Map<String, Object>> cart = findCart(name);
        //2. 删选要购买的（checked:true）  Map --->item 对应的值
        List<OrderItem> checkedOrderItems = cart.stream().filter(e -> (boolean) e.get("checked") == true).map(e -> (OrderItem) e.get("item")).collect(Collectors.toList());
        //3. 从数据库中获取最新的价格
        checkedOrderItems.forEach(orderItem->{

            Sku sku = skuService.findById(orderItem.getSkuId());
            orderItem.setPrice(sku.getPrice());//设置最新的价格给订单项
            orderItem.setMoney(sku.getPrice()*orderItem.getNum());//设置总价

        });
        //4. 同步最新价格数据给购物车
        redisTemplate.boundHashOps("CART_LIST").put(name,cart); //4.同步redis的数据

        return checkedOrderItems;
    }


    /**
     * 新增一个购物车项
     * @param skuId
     * @param num
     * @return
     */
    public Map createNewCartItem(String skuId,Integer num){
        HashMap<String, Object> cartItem = new HashMap<>();//购物车项
        OrderItem orderItem = new OrderItem();
        orderItem.setSkuId(skuId);
        orderItem.setNum(num);
        Sku sku = skuService.findById(skuId);
        orderItem.setImage(sku.getImage());
        orderItem.setPrice(sku.getPrice());
        orderItem.setMoney(sku.getPrice()*num);
        orderItem.setName(sku.getName());
        orderItem.setSpuId(sku.getSpuId());
        if(sku.getWeight()==null) sku.setWeight(0);
        orderItem.setWeight(sku.getWeight()*num);
        orderItem.setCategoryId3(sku.getCategoryId());

        Category category3 = categoryService.findById(sku.getCategoryId());
        orderItem.setCategoryId2(category3.getParentId());

        Category category2 = categoryService.findById(category3.getParentId());
        orderItem.setCategoryId1(category2.getParentId());

        cartItem.put("item",orderItem);
        cartItem.put("checked",false);//默认是不勾选的
      //  cartList.add(cartItem);
        return cartItem;
    }
}
